package com.frinder.base.akka;

import akka.actor.Actor;
import akka.actor.Extension;
import akka.actor.IndirectActorProducer;
import akka.actor.Props;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

/**
 * @ClassName SpringExtension
 * @Author frinder
 * @Description spring akka 整合辅助类
 * @Date 2019/1/19 16:22
 * @Version 1.0
 */
@Component
public class SpringExtension implements Extension {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private ApplicationContext applicationContext;

    public void initialize(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public Props props(String actorBeanName, Object... args) {
        logger.debug("Create Actor : {}", actorBeanName);
        return Props.create(SpringActorProducer.class, applicationContext, actorBeanName, args);
    }

    /**
     *
     */
    static class SpringActorProducer implements IndirectActorProducer {

        private final Logger logger = LoggerFactory.getLogger(getClass());

        final private ApplicationContext applicationContext;
        final private String actorBeanName;
        final private Object[] args;

        public SpringActorProducer(ApplicationContext applicationContext, String actorBeanName, Object... args) {
            this.applicationContext = applicationContext;
            this.actorBeanName = actorBeanName;
            this.args = args;
        }

        @Override
        public Actor produce() {
            logger.debug("ActorBeanName is : {}", actorBeanName);
            return (Actor) applicationContext.getBean(actorBeanName, args);
        }

        @Override
        public Class<? extends Actor> actorClass() {
            return (Class<? extends Actor>) applicationContext.getType(actorBeanName);
        }
    }

}
